﻿



// ===================================
// <copyright>LogoUI Co.</copyright>
// <author>Vlad Spivak</author>
// <email>mailto:vlads@logoui.co.il</email>
// <created>16/00/11</created>
// <lastedit>16/00/11</lastedit>

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the 'Software'), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
//
// <remarks>Part of this software based on various internet sources, mostly on the works
// of members of Wpf Disciples group http://wpfdisciples.wordpress.com/
// Also project may contain code from the frameworks: 
//        Nito - http://nitokitchensink.codeplex.com/
//        OpenLightGroup - http://openlightgroup.net/
//        nRoute - http://nroute.codeplex.com/
//        SilverlightFX - http://projects.nikhilk.net/SilverlightFX
//        BlackLight - http://blacklight.codeplex.com/
// </remarks>
// ====================================================================================//

/*                          Sample Usage
 *      
        <TextBlock Grid.Column="1" x:Name="_tblock" Text="Default"></TextBlock>
        <ListBox ItemsSource="{Binding DataSource}" Grid.Column="0">
            <ListBox.ItemContainerStyle>                
                <Style TargetType="ListBoxItem">
                    <Setter Property="Interactivity:InteractivityItems.Template">
                        <Setter.Value>
                            <Interactivity:InteractivityTemplate>
                                <Interactivity:InteractivityItems>
                                    <Interactivity:InteractivityItems.Behaviors>
                                        <Utils:FlipOnHover></Utils:FlipOnHover>
                                    </Interactivity:InteractivityItems.Behaviors>
                                    <Interactivity:InteractivityItems.Triggers>
                                        <Interactivity1:EventTrigger EventName="MouseMove">
                                            <Interactivity2:TargetedSetPropertyAction PropertyName="Text" TargetObject="{Binding ElementName=_tblock}" Value="{Binding}">
                                            </Interactivity2:TargetedSetPropertyAction>
                                        </Interactivity1:EventTrigger>
                                    </Interactivity:InteractivityItems.Triggers>
                                </Interactivity:InteractivityItems>
                            </Interactivity:InteractivityTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListBox.ItemContainerStyle>
        </ListBox>
 * 
 */
using System.Collections.Generic;

namespace System.Windows.Interactivity
{
    /// <summary>
    /// <see cref="FrameworkTemplate"/> for InteractivityElements instance
    /// <remarks>can't use <see cref="FrameworkTemplate"/> directly due to some internal abstract member</remarks>
    /// </summary>
    public class InteractivityTemplate : DataTemplate
    {

    }

    /// <summary>
    /// Holder for interactivity entries
    /// </summary>
    public class InteractivityItems : FrameworkElement
    {
        private List<Behavior> _behaviors;
        private List<TriggerBase> _triggers;

        /// <summary>
        /// Storage for triggers
        /// </summary>
        public new List<TriggerBase> Triggers
        {
            get { return _triggers ?? (_triggers = new List<TriggerBase>()); }
        }

        /// <summary>
        /// Storage for Behaviors
        /// </summary>
        public List<Behavior> Behaviors
        {
            get { return _behaviors ?? (_behaviors = new List<Behavior>()); }
        }

        #region Template attached property

        public static InteractivityTemplate GetTemplate(DependencyObject obj)
        {
            return (InteractivityTemplate)obj.GetValue(TemplateProperty);
        }

        public static void SetTemplate(DependencyObject obj, InteractivityTemplate value)
        {
            obj.SetValue(TemplateProperty, value);
        }

        public static readonly DependencyProperty TemplateProperty =
            DependencyProperty.RegisterAttached("Template", typeof(InteractivityTemplate), typeof(InteractivityItems),
                                                new PropertyMetadata(default(InteractivityTemplate), OnTemplateChanged));

        private static void OnTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.OldValue != null)
            {
                InteractivityTemplate interactivityTemplate = (InteractivityTemplate)e.OldValue;
                InteractivityItems interactivityItems = (InteractivityItems)interactivityTemplate.LoadContent();
                BehaviorCollection behaviorCollection = Interaction.GetBehaviors(d);
                TriggerCollection triggerCollection = Interaction.GetTriggers(d);

                foreach (Behavior behavior in interactivityItems.Behaviors)
                    behaviorCollection.Remove(behavior);

                foreach (TriggerBase trigger in interactivityItems.Triggers)
                    triggerCollection.Remove(trigger);
            }

            if (e.NewValue != null)
            {
                InteractivityTemplate interactivityTemplate = (InteractivityTemplate)e.NewValue;
#if(!SILVERLIGHT)
            interactivityTemplate.Seal();
#endif
                InteractivityItems interactivityItems = (InteractivityItems)interactivityTemplate.LoadContent();
                BehaviorCollection behaviorCollection = Interaction.GetBehaviors(d);
                TriggerCollection triggerCollection = Interaction.GetTriggers(d);

                foreach (Behavior behavior in interactivityItems.Behaviors)
                    behaviorCollection.Add(behavior);

                foreach (TriggerBase trigger in interactivityItems.Triggers)
                    triggerCollection.Add(trigger);
            }
        }

        #endregion
    }
}
